home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 4
/
MacMania 4.toast
/
/
Tools&Utilities
/
unshar-19
/
CWMPWGlue.cp
next >
Wrap
Text File
|
1995-07-21
|
5KB
|
217 lines
/*********************************************************************
File : CWMPWGlue.cp - Glue code for creating MPW tools with CodeWarrior
Author : Matthias Neeracher <neeri@iis.ee.ethz.ch>
Language : Metrowerks C++
$Log: CWMPWGlue.cp,v $
*********************************************************************/
#include <Types.h>
#include <FragLoad.h>
#include <unix.h>
#include <errno.h>
#include <stdlib.h>
#if !defined(powerc) && !defined(__powerc)
#error "This file is neither needed nor working on an 68K"
#endif
/*********************************************************************
* These procedure pointers will hold the glue routines to the MPW code
*/
static int (*MPW_open)(const char * name, int flags);
static int (*MPW_close)(int s);
static int (*MPW_read)(int s, char *buffer, unsigned buflen);
static int (*MPW_write)(int s, char *buffer, unsigned buflen);
static long (*MPW_lseek)(int fd, long offset, int whence);
static void (*MPW_exit)(int exitcode);
/*
* Initialize glue if necessary. The test is done inline in InitStandardLib,
* while the actual work is done in a separate procedure DoInitStandardLib.
*/
static Boolean beenThereDoneThat = false;
static void DoInitStandardLib()
{
ConnectionID StdCLib;
SymClass symClass;
Ptr whoCares;
Str255 error;
beenThereDoneThat = true;
/*
* We interface to the MPW standard library by dynamically connecting to the
* code fragment. This technique has been suggested to me by Charlie Reiman.
*/
if (GetSharedLibrary(
StringPtr("\pStdCLib"), kPowerPCArch, kLoadLib, &StdCLib, &whoCares, error)
)
return;
if (FindSymbol(StdCLib, StringPtr("\popen"), (Ptr *) &MPW_open, &symClass))
goto failed_on_open;
if (FindSymbol(StdCLib, StringPtr("\pclose"), (Ptr *) &MPW_close, &symClass))
goto failed_on_close;
if (FindSymbol(StdCLib, StringPtr("\pread"), (Ptr *) &MPW_read, &symClass))
goto failed_on_read;
if (FindSymbol(StdCLib, StringPtr("\pwrite"), (Ptr *) &MPW_write, &symClass))
goto failed_on_write;
if (FindSymbol(StdCLib, StringPtr("\plseek"), (Ptr *) &MPW_lseek, &symClass))
goto failed_on_lseek;
if (FindSymbol(StdCLib, StringPtr("\pexit"), (Ptr *) &MPW_exit, &symClass))
goto failed_on_exit;
return;
failed_on_exit:
MPW_exit = nil;
failed_on_lseek:
MPW_lseek = nil;
failed_on_write:
MPW_write = nil;
failed_on_read:
MPW_read = nil;
failed_on_close:
MPW_close = nil;
failed_on_open:
MPW_open = nil;
}
inline void InitStandardLib()
{
if (beenThereDoneThat)
return;
DoInitStandardLib();
}
/*
* Set errno if an error occurred. The Metrowerks library knows few error codes,
* so we simply return EDOM regardless of the actual error.
*/
inline int Error(int res)
{
if (res == -1)
errno = EDOM;
return res;
}
inline long Error(long res)
{
if (res == -1)
errno = EDOM;
return res;
}
#define MPW_O_RDONLY 0 /* Bits 0 and 1 are used internally */
#define MPW_O_WRONLY 1 /* Values 0..2 are historical */
#define MPW_O_RDWR 2 /* NOTE: it goes 0, 1, 2, *!* 8, 16, 32, ... */
#define MPW_O_APPEND (1<< 3) /* append (writes guaranteed at the end) */
#define MPW_O_RSRC (1<< 4) /* Open the resource fork */
#define MPW_O_ALIAS (1<< 5) /* Open alias file */
#define MPW_O_CREAT (1<< 8) /* Open with file create */
#define MPW_O_TRUNC (1<< 9) /* Open with truncation */
#define MPW_O_EXCL (1<<10) /* w/ O_CREAT: Exclusive "create-only" */
#define MPW_O_BINARY (1<<11) /* Open as a binary stream */
#define MPW_O_NRESOLVE (1<<14) /* Don't resolve any aliases */
static int TranslateOpenFlags(int mode)
{
int mpwMode;
switch (mode & 3) {
case O_RDWR:
mpwMode = MPW_O_RDWR;
break;
case O_RDONLY:
mpwMode = MPW_O_RDONLY;
break;
case O_WRONLY:
mpwMode = MPW_O_WRONLY;
break;
}
if (mode & O_APPEND)
mpwMode |= MPW_O_APPEND;
if (mode & O_CREAT)
mpwMode |= MPW_O_CREAT;
if (mode & O_EXCL)
mpwMode |= MPW_O_EXCL;
if (mode & O_TRUNC)
mpwMode |= MPW_O_TRUNC;
if (mode & O_BINARY)
mpwMode |= MPW_O_BINARY;
return mpwMode;
}
/*
* Opens a file and returns it's id.
*/
int open(const char *filename, int mode)
{
InitStandardLib();
return Error(MPW_open ? MPW_open(filename, TranslateOpenFlags(mode)) : -1);
}
/*
* Reads from a file stream.
*/
int read(int fd, char *buf, int count)
{
InitStandardLib();
return Error(MPW_read ? MPW_read(fd, buf, count) : -1);
}
/*
* Writes to a file stream.
*/
int write(int fd, const char *buf, int count)
{
InitStandardLib();
return Error(MPW_write ? MPW_write(fd, (char *) buf, count) : -1);
}
/*
* Seek on a file stream.
*/
long lseek(int fd, long offset, int whence)
{
/* whence constants for MPW and CodeWarrior are identical */
InitStandardLib();
return Error(MPW_lseek ? MPW_lseek(fd, offset, whence) : -1);
}
/*
* Closes an open file.
*/
int close(int fd)
{
InitStandardLib();
return Error(MPW_close ? MPW_close(fd) : -1);
}
/*
* Closes an open file.
*/
void exit(int code)
{
int i;
for (i=0; i<FOPEN_MAX; i++)
if (_Files[i])
fclose(_Files[i]);
InitStandardLib();
if (MPW_exit)
MPW_exit(code);
}
/* Stub for RemoveConsole */
extern "C" void RemoveConsole(void)
{
}